home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume13 / rpc3.9 / part04 < prev    next >
Encoding:
Internet Message Format  |  1988-02-27  |  53.6 KB

  1. Subject:  v13i081:  Sun RPC, release 3.9, Part04/10
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Stephen X. Nahm <sxn@Sun.COM>
  7. Posting-number: Volume 13, Issue 81
  8. Archive-name: rpc3.9/part04
  9.  
  10. #! /bin/sh
  11. # This is a shell archive. To extract, remove the header and type "sh filename"
  12. #
  13. cd rpc
  14. echo x - svc.h
  15. cat > svc.h <<'Funky_Stuff'
  16. /* @(#)svc.h    1.2 87/11/09 3.9 RPCSRC */
  17. /*
  18.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  19.  * unrestricted use provided that this legend is included on all tape
  20.  * media and as a part of the software program in whole or part.  Users
  21.  * may copy or modify Sun RPC without charge, but are not authorized
  22.  * to license or distribute it to anyone else except as part of a product or
  23.  * program developed by the user.
  24.  * 
  25.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  26.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  27.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  28.  * 
  29.  * Sun RPC is provided with no support and without any obligation on the
  30.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  31.  * modification or enhancement.
  32.  * 
  33.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  34.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  35.  * OR ANY PART THEREOF.
  36.  * 
  37.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  38.  * or profits or other special, indirect and consequential damages, even if
  39.  * Sun has been advised of the possibility of such damages.
  40.  * 
  41.  * Sun Microsystems, Inc.
  42.  * 2550 Garcia Avenue
  43.  * Mountain View, California  94043
  44.  */
  45. /*      @(#)svc.h 1.18 87/07/14 SMI      *
  46.  
  47. /*
  48.  * svc.h, Server-side remote procedure call interface.
  49.  *
  50.  * Copyright (C) 1984, Sun Microsystems, Inc.
  51.  */
  52.  
  53. #ifndef __SVC_HEADER__
  54. #define __SVC_HEADER__
  55.  
  56. /*
  57.  * This interface must manage two items concerning remote procedure calling:
  58.  *
  59.  * 1) An arbitrary number of transport connections upon which rpc requests
  60.  * are received.  The two most notable transports are TCP and UDP;  they are
  61.  * created and registered by routines in svc_tcp.c and svc_udp.c, respectively;
  62.  * they in turn call xprt_register and xprt_unregister.
  63.  *
  64.  * 2) An arbitrary number of locally registered services.  Services are
  65.  * described by the following four data: program number, version number,
  66.  * "service dispatch" function, a transport handle, and a boolean that
  67.  * indicates whether or not the exported program should be registered with a
  68.  * local binder service;  if true the program's number and version and the
  69.  * port number from the transport handle are registered with the binder.
  70.  * These data are registered with the rpc svc system via svc_register.
  71.  *
  72.  * A service's dispatch function is called whenever an rpc request comes in
  73.  * on a transport.  The request's program and version numbers must match
  74.  * those of the registered service.  The dispatch function is passed two
  75.  * parameters, struct svc_req * and SVCXPRT *, defined below.
  76.  */
  77.  
  78. enum xprt_stat {
  79.     XPRT_DIED,
  80.     XPRT_MOREREQS,
  81.     XPRT_IDLE
  82. };
  83.  
  84. /*
  85.  * Server side transport handle
  86.  */
  87. typedef struct {
  88.     int        xp_sock;
  89.     u_short        xp_port;     /* associated port number */
  90.     struct xp_ops {
  91.         bool_t    (*xp_recv)();     /* receive incomming requests */
  92.         enum xprt_stat (*xp_stat)(); /* get transport status */
  93.         bool_t    (*xp_getargs)(); /* get arguments */
  94.         bool_t    (*xp_reply)();     /* send reply */
  95.         bool_t    (*xp_freeargs)();/* free mem allocated for args */
  96.         void    (*xp_destroy)(); /* destroy this struct */
  97.     } *xp_ops;
  98.     int        xp_addrlen;     /* length of remote address */
  99.     struct sockaddr_in xp_raddr;     /* remote address */
  100.     struct opaque_auth xp_verf;     /* raw response verifier */
  101.     caddr_t        xp_p1;         /* private */
  102.     caddr_t        xp_p2;         /* private */
  103. } SVCXPRT;
  104.  
  105. /*
  106.  *  Approved way of getting address of caller
  107.  */
  108. #define svc_getcaller(x) (&(x)->xp_raddr)
  109.  
  110. /*
  111.  * Operations defined on an SVCXPRT handle
  112.  *
  113.  * SVCXPRT        *xprt;
  114.  * struct rpc_msg    *msg;
  115.  * xdrproc_t         xargs;
  116.  * caddr_t         argsp;
  117.  */
  118. #define SVC_RECV(xprt, msg)                \
  119.     (*(xprt)->xp_ops->xp_recv)((xprt), (msg))
  120. #define svc_recv(xprt, msg)                \
  121.     (*(xprt)->xp_ops->xp_recv)((xprt), (msg))
  122.  
  123. #define SVC_STAT(xprt)                    \
  124.     (*(xprt)->xp_ops->xp_stat)(xprt)
  125. #define svc_stat(xprt)                    \
  126.     (*(xprt)->xp_ops->xp_stat)(xprt)
  127.  
  128. #define SVC_GETARGS(xprt, xargs, argsp)            \
  129.     (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp))
  130. #define svc_getargs(xprt, xargs, argsp)            \
  131.     (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp))
  132.  
  133. #define SVC_REPLY(xprt, msg)                \
  134.     (*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
  135. #define svc_reply(xprt, msg)                \
  136.     (*(xprt)->xp_ops->xp_reply) ((xprt), (msg))
  137.  
  138. #define SVC_FREEARGS(xprt, xargs, argsp)        \
  139.     (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp))
  140. #define svc_freeargs(xprt, xargs, argsp)        \
  141.     (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp))
  142.  
  143. #define SVC_DESTROY(xprt)                \
  144.     (*(xprt)->xp_ops->xp_destroy)(xprt)
  145. #define svc_destroy(xprt)                \
  146.     (*(xprt)->xp_ops->xp_destroy)(xprt)
  147.  
  148.  
  149. /*
  150.  * Service request
  151.  */
  152. struct svc_req {
  153.     u_long        rq_prog;    /* service program number */
  154.     u_long        rq_vers;    /* service protocol version */
  155.     u_long        rq_proc;    /* the desired procedure */
  156.     struct opaque_auth rq_cred;    /* raw creds from the wire */
  157.     caddr_t        rq_clntcred;    /* read only cooked cred */
  158.     SVCXPRT    *rq_xprt;        /* associated transport */
  159. };
  160.  
  161.  
  162. /*
  163.  * Service registration
  164.  *
  165.  * svc_register(xprt, prog, vers, dispatch, protocol)
  166.  *    SVCXPRT *xprt;
  167.  *    u_long prog;
  168.  *    u_long vers;
  169.  *    void (*dispatch)();
  170.  *    int protocol;  /* like TCP or UDP, zero means do not register 
  171.  */
  172. extern bool_t    svc_register();
  173.  
  174. /*
  175.  * Service un-registration
  176.  *
  177.  * svc_unregister(prog, vers)
  178.  *    u_long prog;
  179.  *    u_long vers;
  180.  */
  181. extern void    svc_unregister();
  182.  
  183. /*
  184.  * Transport registration.
  185.  *
  186.  * xprt_register(xprt)
  187.  *    SVCXPRT *xprt;
  188.  */
  189. extern void    xprt_register();
  190.  
  191. /*
  192.  * Transport un-register
  193.  *
  194.  * xprt_unregister(xprt)
  195.  *    SVCXPRT *xprt;
  196.  */
  197. extern void    xprt_unregister();
  198.  
  199.  
  200.  
  201.  
  202. /*
  203.  * When the service routine is called, it must first check to see if it
  204.  * knows about the procedure;  if not, it should call svcerr_noproc
  205.  * and return.  If so, it should deserialize its arguments via 
  206.  * SVC_GETARGS (defined above).  If the deserialization does not work,
  207.  * svcerr_decode should be called followed by a return.  Successful
  208.  * decoding of the arguments should be followed the execution of the
  209.  * procedure's code and a call to svc_sendreply.
  210.  *
  211.  * Also, if the service refuses to execute the procedure due to too-
  212.  * weak authentication parameters, svcerr_weakauth should be called.
  213.  * Note: do not confuse access-control failure with weak authentication!
  214.  *
  215.  * NB: In pure implementations of rpc, the caller always waits for a reply
  216.  * msg.  This message is sent when svc_sendreply is called.  
  217.  * Therefore pure service implementations should always call
  218.  * svc_sendreply even if the function logically returns void;  use
  219.  * xdr.h - xdr_void for the xdr routine.  HOWEVER, tcp based rpc allows
  220.  * for the abuse of pure rpc via batched calling or pipelining.  In the
  221.  * case of a batched call, svc_sendreply should NOT be called since
  222.  * this would send a return message, which is what batching tries to avoid.
  223.  * It is the service/protocol writer's responsibility to know which calls are
  224.  * batched and which are not.  Warning: responding to batch calls may
  225.  * deadlock the caller and server processes!
  226.  */
  227.  
  228. extern bool_t  svc_sendreply();
  229. extern void    svcerr_decode();
  230. extern void    svcerr_weakauth();
  231. extern void    svcerr_noproc();
  232.  
  233. /*
  234.  * Lowest level dispatching -OR- who owns this process anyway.
  235.  * Somebody has to wait for incoming requests and then call the correct
  236.  * service routine.  The routine svc_run does infinite waiting; i.e.,
  237.  * svc_run never returns.
  238.  * Since another (co-existant) package may wish to selectively wait for
  239.  * incoming calls or other events outside of the rpc architecture, the
  240.  * routine svc_getreq is provided.  It must be passed readfds, the
  241.  * "in-place" results of a select system call (see select, section 2).
  242.  */
  243.  
  244. /*
  245.  * Global keeper of rpc service descriptors in use
  246.  * dynamic; must be inspected before each call to select 
  247.  */
  248. #ifdef FD_SETSIZE
  249. extern fd_set svc_fdset;
  250. #define svc_fds svc_fdset.fds_bits[0]    /* compatibility */
  251. #else
  252. extern int svc_fds;
  253. #endif /* def FD_SETSIZE */
  254.  
  255. /*
  256.  * a small program implemented by the svc_rpc implementation itself;
  257.  * also see clnt.h for protocol numbers.
  258.  */
  259. extern void rpctest_service();
  260.  
  261. extern void    svc_getreq();
  262. extern void    svc_getreqset();    /* takes fdset instead of int */
  263. extern void    svc_run();      /* never returns */
  264.  
  265. /*
  266.  * Socket to use on svcxxx_create call to get default socket
  267.  */
  268. #define    RPC_ANYSOCK    -1
  269.  
  270. /*
  271.  * These are the existing service side transport implementations
  272.  */
  273.  
  274. /*
  275.  * Memory based rpc for testing and timing.
  276.  */
  277. extern SVCXPRT *svcraw_create();
  278.  
  279. /*
  280.  * Udp based rpc.
  281.  */
  282. extern SVCXPRT *svcudp_create();
  283. extern SVCXPRT *svcudp_bufcreate();
  284.  
  285. /*
  286.  * Tcp based rpc.
  287.  */
  288. extern SVCXPRT *svctcp_create();
  289.  
  290.  
  291.  
  292. #endif !__SVC_HEADER__
  293. Funky_Stuff
  294. len=`wc -c < svc.h`
  295. if [ $len !=     8701 ] ; then
  296.   echo error: svc.h was $len bytes long, should have been     8701
  297. fi
  298. echo x - svc_auth.c
  299. cat > svc_auth.c <<'Funky_Stuff'
  300. /* @(#)svc_auth.c    1.1 87/11/04 3.9 RPCSRC */
  301. /*
  302.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  303.  * unrestricted use provided that this legend is included on all tape
  304.  * media and as a part of the software program in whole or part.  Users
  305.  * may copy or modify Sun RPC without charge, but are not authorized
  306.  * to license or distribute it to anyone else except as part of a product or
  307.  * program developed by the user.
  308.  * 
  309.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  310.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  311.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  312.  * 
  313.  * Sun RPC is provided with no support and without any obligation on the
  314.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  315.  * modification or enhancement.
  316.  * 
  317.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  318.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  319.  * OR ANY PART THEREOF.
  320.  * 
  321.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  322.  * or profits or other special, indirect and consequential damages, even if
  323.  * Sun has been advised of the possibility of such damages.
  324.  * 
  325.  * Sun Microsystems, Inc.
  326.  * 2550 Garcia Avenue
  327.  * Mountain View, California  94043
  328.  */
  329. #if !defined(lint) && defined(SCCSIDS)
  330. static char sccsid[] = "@(#)svc_auth.c 1.19 87/08/11 Copyr 1984 Sun Micro";
  331. #endif
  332.  
  333. /*
  334.  * svc_auth.c, Server-side rpc authenticator interface.
  335.  *
  336.  * Copyright (C) 1984, Sun Microsystems, Inc.
  337.  */
  338.  
  339. #include <rpc/rpc.h>
  340.  
  341. /*
  342.  * svcauthsw is the bdevsw of server side authentication. 
  343.  * 
  344.  * Server side authenticators are called from authenticate by
  345.  * using the client auth struct flavor field to index into svcauthsw.
  346.  * The server auth flavors must implement a routine that looks  
  347.  * like: 
  348.  * 
  349.  *    enum auth_stat
  350.  *    flavorx_auth(rqst, msg)
  351.  *        register struct svc_req *rqst; 
  352.  *        register struct rpc_msg *msg;
  353.  *
  354.  */
  355.  
  356. enum auth_stat _svcauth_null();        /* no authentication */
  357. enum auth_stat _svcauth_unix();        /* unix style (uid, gids) */
  358. enum auth_stat _svcauth_short();    /* short hand unix style */
  359.  
  360. static struct {
  361.     enum auth_stat (*authenticator)();
  362. } svcauthsw[] = {
  363.     _svcauth_null,            /* AUTH_NULL */
  364.     _svcauth_unix,            /* AUTH_UNIX */
  365.     _svcauth_short,            /* AUTH_SHORT */
  366. };
  367. #define    AUTH_MAX    2        /* HIGHEST AUTH NUMBER */
  368.  
  369.  
  370. /*
  371.  * The call rpc message, msg has been obtained from the wire.  The msg contains
  372.  * the raw form of credentials and verifiers.  authenticate returns AUTH_OK
  373.  * if the msg is successfully authenticated.  If AUTH_OK then the routine also
  374.  * does the following things:
  375.  * set rqst->rq_xprt->verf to the appropriate response verifier;
  376.  * sets rqst->rq_client_cred to the "cooked" form of the credentials.
  377.  *
  378.  * NB: rqst->rq_cxprt->verf must be pre-alloctaed;
  379.  * its length is set appropriately.
  380.  *
  381.  * The caller still owns and is responsible for msg->u.cmb.cred and
  382.  * msg->u.cmb.verf.  The authentication system retains ownership of
  383.  * rqst->rq_client_cred, the cooked credentials.
  384.  *
  385.  * There is an assumption that any flavour less than AUTH_NULL is
  386.  * invalid.
  387.  */
  388. enum auth_stat
  389. _authenticate(rqst, msg)
  390.     register struct svc_req *rqst;
  391.     struct rpc_msg *msg;
  392. {
  393.     register int cred_flavor;
  394.  
  395.     rqst->rq_cred = msg->rm_call.cb_cred;
  396.     rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor;
  397.     rqst->rq_xprt->xp_verf.oa_length = 0;
  398.     cred_flavor = rqst->rq_cred.oa_flavor;
  399.     if ((cred_flavor <= AUTH_MAX) && (cred_flavor >= AUTH_NULL)) {
  400.         return ((*(svcauthsw[cred_flavor].authenticator))(rqst, msg));
  401.     }
  402.  
  403.     return (AUTH_REJECTEDCRED);
  404. }
  405.  
  406. enum auth_stat
  407. _svcauth_null(/*rqst, msg*/)
  408.     /*struct svc_req *rqst;
  409.     struct rpc_msg *msg;*/
  410. {
  411.  
  412.     return (AUTH_OK);
  413. }
  414. Funky_Stuff
  415. len=`wc -c < svc_auth.c`
  416. if [ $len !=     3726 ] ; then
  417.   echo error: svc_auth.c was $len bytes long, should have been     3726
  418. fi
  419. echo x - svc_auth.h
  420. cat > svc_auth.h <<'Funky_Stuff'
  421. /* @(#)svc_auth.h    1.1 87/11/04 3.9 RPCSRC */
  422. /*
  423.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  424.  * unrestricted use provided that this legend is included on all tape
  425.  * media and as a part of the software program in whole or part.  Users
  426.  * may copy or modify Sun RPC without charge, but are not authorized
  427.  * to license or distribute it to anyone else except as part of a product or
  428.  * program developed by the user.
  429.  * 
  430.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  431.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  432.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  433.  * 
  434.  * Sun RPC is provided with no support and without any obligation on the
  435.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  436.  * modification or enhancement.
  437.  * 
  438.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  439.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  440.  * OR ANY PART THEREOF.
  441.  * 
  442.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  443.  * or profits or other special, indirect and consequential damages, even if
  444.  * Sun has been advised of the possibility of such damages.
  445.  * 
  446.  * Sun Microsystems, Inc.
  447.  * 2550 Garcia Avenue
  448.  * Mountain View, California  94043
  449.  */
  450. /*      @(#)svc_auth.h 1.6 86/07/16 SMI      */
  451.  
  452. /*
  453.  * svc_auth.h, Service side of rpc authentication.
  454.  * 
  455.  * Copyright (C) 1984, Sun Microsystems, Inc.
  456.  */
  457.  
  458.  
  459. /*
  460.  * Server side authenticator
  461.  */
  462. extern enum auth_stat _authenticate();
  463. Funky_Stuff
  464. len=`wc -c < svc_auth.h`
  465. if [ $len !=     1548 ] ; then
  466.   echo error: svc_auth.h was $len bytes long, should have been     1548
  467. fi
  468. echo x - svc_auth_unix.c
  469. cat > svc_auth_unix.c <<'Funky_Stuff'
  470. /* @(#)svc_auth_unix.c    1.1 87/11/04 3.9 RPCSRC */
  471. /*
  472.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  473.  * unrestricted use provided that this legend is included on all tape
  474.  * media and as a part of the software program in whole or part.  Users
  475.  * may copy or modify Sun RPC without charge, but are not authorized
  476.  * to license or distribute it to anyone else except as part of a product or
  477.  * program developed by the user.
  478.  * 
  479.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  480.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  481.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  482.  * 
  483.  * Sun RPC is provided with no support and without any obligation on the
  484.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  485.  * modification or enhancement.
  486.  * 
  487.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  488.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  489.  * OR ANY PART THEREOF.
  490.  * 
  491.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  492.  * or profits or other special, indirect and consequential damages, even if
  493.  * Sun has been advised of the possibility of such damages.
  494.  * 
  495.  * Sun Microsystems, Inc.
  496.  * 2550 Garcia Avenue
  497.  * Mountain View, California  94043
  498.  */
  499. #if !defined(lint) && defined(SCCSIDS)
  500. static char sccsid[] = "@(#)svc_auth_unix.c 1.26 87/08/11 Copyr 1984 Sun Micro";
  501. #endif
  502.  
  503. /*
  504.  * svc_auth_unix.c
  505.  * Handles UNIX flavor authentication parameters on the service side of rpc.
  506.  * There are two svc auth implementations here: AUTH_UNIX and AUTH_SHORT.
  507.  * _svcauth_unix does full blown unix style uid,gid+gids auth,
  508.  * _svcauth_short uses a shorthand auth to index into a cache of longhand auths.
  509.  * Note: the shorthand has been gutted for efficiency.
  510.  *
  511.  * Copyright (C) 1984, Sun Microsystems, Inc.
  512.  */
  513.  
  514. #include <stdio.h>
  515. #include <sys/time.h>
  516. #include <rpc/rpc.h>
  517.  
  518. /*
  519.  * Unix longhand authenticator
  520.  */
  521. enum auth_stat
  522. _svcauth_unix(rqst, msg)
  523.     register struct svc_req *rqst;
  524.     register struct rpc_msg *msg;
  525. {
  526.     register enum auth_stat stat;
  527.     XDR xdrs;
  528.     register struct authunix_parms *aup;
  529.     register long *buf;
  530.     struct area {
  531.         struct authunix_parms area_aup;
  532.         char area_machname[MAX_MACHINE_NAME];
  533.         int area_gids[NGRPS];
  534.     } *area;
  535.     u_int auth_len;
  536.     int str_len, gid_len;
  537.     register int i;
  538.  
  539.     area = (struct area *) rqst->rq_clntcred;
  540.     aup = &area->area_aup;
  541.     aup->aup_machname = area->area_machname;
  542.     aup->aup_gids = area->area_gids;
  543.     auth_len = (u_int)msg->rm_call.cb_cred.oa_length;
  544.     xdrmem_create(&xdrs, msg->rm_call.cb_cred.oa_base, auth_len,XDR_DECODE);
  545.     buf = XDR_INLINE(&xdrs, auth_len);
  546.     if (buf != NULL) {
  547.         aup->aup_time = IXDR_GET_LONG(buf);
  548.         str_len = IXDR_GET_U_LONG(buf);
  549.         bcopy((caddr_t)buf, aup->aup_machname, (u_int)str_len);
  550.         aup->aup_machname[str_len] = 0;
  551.         str_len = RNDUP(str_len);
  552.         buf += str_len / sizeof (long);
  553.         aup->aup_uid = IXDR_GET_LONG(buf);
  554.         aup->aup_gid = IXDR_GET_LONG(buf);
  555.         gid_len = IXDR_GET_U_LONG(buf);
  556.         if (gid_len > NGRPS) {
  557.             stat = AUTH_BADCRED;
  558.             goto done;
  559.         }
  560.         aup->aup_len = gid_len;
  561.         for (i = 0; i < gid_len; i++) {
  562.             aup->aup_gids[i] = IXDR_GET_LONG(buf);
  563.         }
  564.         /*
  565.          * five is the smallest unix credentials structure -
  566.          * timestamp, hostname len (0), uid, gid, and gids len (0).
  567.          */
  568.         if ((5 + gid_len) * BYTES_PER_XDR_UNIT + str_len > auth_len) {
  569.             (void) printf("bad auth_len gid %d str %d auth %d\n",
  570.                 gid_len, str_len, auth_len);
  571.             stat = AUTH_BADCRED;
  572.             goto done;
  573.         }
  574.     } else if (! xdr_authunix_parms(&xdrs, aup)) {
  575.         xdrs.x_op = XDR_FREE;
  576.         (void)xdr_authunix_parms(&xdrs, aup);
  577.         stat = AUTH_BADCRED;
  578.         goto done;
  579.     }
  580.     rqst->rq_xprt->xp_verf.oa_flavor = AUTH_NULL;
  581.     rqst->rq_xprt->xp_verf.oa_length = 0;
  582.     stat = AUTH_OK;
  583. done:
  584.     XDR_DESTROY(&xdrs);
  585.     return (stat);
  586. }
  587.  
  588.  
  589. /*
  590.  * Shorthand unix authenticator
  591.  * Looks up longhand in a cache.
  592.  */
  593. /*ARGSUSED*/
  594. enum auth_stat 
  595. _svcauth_short(rqst, msg)
  596.     struct svc_req *rqst;
  597.     struct rpc_msg *msg;
  598. {
  599.     return (AUTH_REJECTEDCRED);
  600. }
  601. Funky_Stuff
  602. len=`wc -c < svc_auth_unix.c`
  603. if [ $len !=     4026 ] ; then
  604.   echo error: svc_auth_unix.c was $len bytes long, should have been     4026
  605. fi
  606. echo x - svc_raw.c
  607. cat > svc_raw.c <<'Funky_Stuff'
  608. /* @(#)svc_raw.c    1.1 87/11/04 3.9 RPCSRC */
  609. /*
  610.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  611.  * unrestricted use provided that this legend is included on all tape
  612.  * media and as a part of the software program in whole or part.  Users
  613.  * may copy or modify Sun RPC without charge, but are not authorized
  614.  * to license or distribute it to anyone else except as part of a product or
  615.  * program developed by the user.
  616.  * 
  617.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  618.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  619.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  620.  * 
  621.  * Sun RPC is provided with no support and without any obligation on the
  622.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  623.  * modification or enhancement.
  624.  * 
  625.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  626.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  627.  * OR ANY PART THEREOF.
  628.  * 
  629.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  630.  * or profits or other special, indirect and consequential damages, even if
  631.  * Sun has been advised of the possibility of such damages.
  632.  * 
  633.  * Sun Microsystems, Inc.
  634.  * 2550 Garcia Avenue
  635.  * Mountain View, California  94043
  636.  */
  637. #if !defined(lint) && defined(SCCSIDS)
  638. static char sccsid[] = "@(#)svc_raw.c 1.15 87/08/11 Copyr 1984 Sun Micro";
  639. #endif
  640.  
  641. /*
  642.  * svc_raw.c,   This a toy for simple testing and timing.
  643.  * Interface to create an rpc client and server in the same UNIX process.
  644.  * This lets us similate rpc and get rpc (round trip) overhead, without
  645.  * any interference from the kernal.
  646.  *
  647.  * Copyright (C) 1984, Sun Microsystems, Inc.
  648.  */
  649.  
  650. #include <rpc/rpc.h>
  651.  
  652.  
  653. /*
  654.  * This is the "network" that we will be moving data over
  655.  */
  656. static struct svcraw_private {
  657.     char    _raw_buf[UDPMSGSIZE];
  658.     SVCXPRT    server;
  659.     XDR    xdr_stream;
  660.     char    verf_body[MAX_AUTH_BYTES];
  661. } *svcraw_private;
  662.  
  663. static bool_t        svcraw_recv();
  664. static enum xprt_stat     svcraw_stat();
  665. static bool_t        svcraw_getargs();
  666. static bool_t        svcraw_reply();
  667. static bool_t        svcraw_freeargs();
  668. static void        svcraw_destroy();
  669.  
  670. static struct xp_ops server_ops = {
  671.     svcraw_recv,
  672.     svcraw_stat,
  673.     svcraw_getargs,
  674.     svcraw_reply,
  675.     svcraw_freeargs,
  676.     svcraw_destroy
  677. };
  678.  
  679. SVCXPRT *
  680. svcraw_create()
  681. {
  682.     register struct svcraw_private *srp = svcraw_private;
  683.  
  684.     if (srp == 0) {
  685.         srp = (struct svcraw_private *)calloc(1, sizeof (*srp));
  686.         if (srp == 0)
  687.             return (0);
  688.     }
  689.     srp->server.xp_sock = 0;
  690.     srp->server.xp_port = 0;
  691.     srp->server.xp_ops = &server_ops;
  692.     srp->server.xp_verf.oa_base = srp->verf_body;
  693.     xdrmem_create(&srp->xdr_stream, srp->_raw_buf, UDPMSGSIZE, XDR_FREE);
  694.     return (&srp->server);
  695. }
  696.  
  697. static enum xprt_stat
  698. svcraw_stat()
  699. {
  700.  
  701.     return (XPRT_IDLE);
  702. }
  703.  
  704. static bool_t
  705. svcraw_recv(xprt, msg)
  706.     SVCXPRT *xprt;
  707.     struct rpc_msg *msg;
  708. {
  709.     register struct svcraw_private *srp = svcraw_private;
  710.     register XDR *xdrs;
  711.  
  712.     if (srp == 0)
  713.         return (0);
  714.     xdrs = &srp->xdr_stream;
  715.     xdrs->x_op = XDR_DECODE;
  716.     XDR_SETPOS(xdrs, 0);
  717.     if (! xdr_callmsg(xdrs, msg))
  718.            return (FALSE);
  719.     return (TRUE);
  720. }
  721.  
  722. static bool_t
  723. svcraw_reply(xprt, msg)
  724.     SVCXPRT *xprt;
  725.     struct rpc_msg *msg;
  726. {
  727.     register struct svcraw_private *srp = svcraw_private;
  728.     register XDR *xdrs;
  729.  
  730.     if (srp == 0)
  731.         return (FALSE);
  732.     xdrs = &srp->xdr_stream;
  733.     xdrs->x_op = XDR_ENCODE;
  734.     XDR_SETPOS(xdrs, 0);
  735.     if (! xdr_replymsg(xdrs, msg))
  736.            return (FALSE);
  737.     (void)XDR_GETPOS(xdrs);  /* called just for overhead */
  738.     return (TRUE);
  739. }
  740.  
  741. static bool_t
  742. svcraw_getargs(xprt, xdr_args, args_ptr)
  743.     SVCXPRT *xprt;
  744.     xdrproc_t xdr_args;
  745.     caddr_t args_ptr;
  746. {
  747.     register struct svcraw_private *srp = svcraw_private;
  748.  
  749.     if (srp == 0)
  750.         return (FALSE);
  751.     return ((*xdr_args)(&srp->xdr_stream, args_ptr));
  752. }
  753.  
  754. static bool_t
  755. svcraw_freeargs(xprt, xdr_args, args_ptr)
  756.     SVCXPRT *xprt;
  757.     xdrproc_t xdr_args;
  758.     caddr_t args_ptr;
  759.     register struct svcraw_private *srp = svcraw_private;
  760.     register XDR *xdrs;
  761.  
  762.     if (srp == 0)
  763.         return (FALSE);
  764.     xdrs = &srp->xdr_stream;
  765.     xdrs->x_op = XDR_FREE;
  766.     return ((*xdr_args)(xdrs, args_ptr));
  767.  
  768. static void
  769. svcraw_destroy()
  770. {
  771. }
  772. Funky_Stuff
  773. len=`wc -c < svc_raw.c`
  774. if [ $len !=     4120 ] ; then
  775.   echo error: svc_raw.c was $len bytes long, should have been     4120
  776. fi
  777. echo x - svc_run.c
  778. cat > svc_run.c <<'Funky_Stuff'
  779. /* @(#)svc_run.c    1.3 87/11/13 3.9 RPCSRC */
  780. #if !defined(lint) && defined(SCCSIDS)
  781. static char sccsid[] = "@(#)svc_run.c 1.1 87/10/13 Copyr 1984 Sun Micro";
  782. #endif
  783.  
  784. /*
  785.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  786.  * unrestricted use provided that this legend is included on all tape
  787.  * media and as a part of the software program in whole or part.  Users
  788.  * may copy or modify Sun RPC without charge, but are not authorized
  789.  * to license or distribute it to anyone else except as part of a product or
  790.  * program developed by the user.
  791.  * 
  792.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  793.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  794.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  795.  * 
  796.  * Sun RPC is provided with no support and without any obligation on the
  797.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  798.  * modification or enhancement.
  799.  * 
  800.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  801.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  802.  * OR ANY PART THEREOF.
  803.  * 
  804.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  805.  * or profits or other special, indirect and consequential damages, even if
  806.  * Sun has been advised of the possibility of such damages.
  807.  * 
  808.  * Sun Microsystems, Inc.
  809.  * 2550 Garcia Avenue
  810.  * Mountain View, California  94043
  811.  */
  812.  
  813. /*
  814.  * This is the rpc server side idle loop
  815.  * Wait for input, call server program.
  816.  */
  817. #include <rpc/rpc.h>
  818. #include <sys/errno.h>
  819.  
  820. void
  821. svc_run()
  822. {
  823. #ifdef FD_SETSIZE
  824.     fd_set readfds;
  825. #else
  826.       int readfds;
  827. #endif /* def FD_SETSIZE */
  828.     extern int errno;
  829.  
  830.     for (;;) {
  831. #ifdef FD_SETSIZE
  832.         readfds = svc_fdset;
  833. #else
  834.         readfds = svc_fds;
  835. #endif /* def FD_SETSIZE */
  836.         switch (select(_rpc_dtablesize(), &readfds, (int *)0, (int *)0,
  837.                    (struct timeval *)0)) {
  838.         case -1:
  839.             if (errno == EINTR) {
  840.                 continue;
  841.             }
  842.             perror("svc_run: - select failed");
  843.             return;
  844.         case 0:
  845.             continue;
  846.         default:
  847.             svc_getreqset(&readfds);
  848.         }
  849.     }
  850. }
  851. Funky_Stuff
  852. len=`wc -c < svc_run.c`
  853. if [ $len !=     2077 ] ; then
  854.   echo error: svc_run.c was $len bytes long, should have been     2077
  855. fi
  856. echo x - svc_simple.c
  857. cat > svc_simple.c <<'Funky_Stuff'
  858. /* @(#)svc_simple.c    1.1 87/11/04 3.9 RPCSRC */
  859. /*
  860.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  861.  * unrestricted use provided that this legend is included on all tape
  862.  * media and as a part of the software program in whole or part.  Users
  863.  * may copy or modify Sun RPC without charge, but are not authorized
  864.  * to license or distribute it to anyone else except as part of a product or
  865.  * program developed by the user.
  866.  * 
  867.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  868.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  869.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  870.  * 
  871.  * Sun RPC is provided with no support and without any obligation on the
  872.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  873.  * modification or enhancement.
  874.  * 
  875.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  876.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  877.  * OR ANY PART THEREOF.
  878.  * 
  879.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  880.  * or profits or other special, indirect and consequential damages, even if
  881.  * Sun has been advised of the possibility of such damages.
  882.  * 
  883.  * Sun Microsystems, Inc.
  884.  * 2550 Garcia Avenue
  885.  * Mountain View, California  94043
  886.  */
  887. #if !defined(lint) && defined(SCCSIDS)
  888. static char sccsid[] = "@(#)svc_simple.c 1.18 87/08/11 Copyr 1984 Sun Micro";
  889. #endif
  890.  
  891. /* 
  892.  * svc_simple.c
  893.  * Simplified front end to rpc.
  894.  *
  895.  * Copyright (C) 1984, Sun Microsystems, Inc.
  896.  */
  897.  
  898. #include <stdio.h>
  899. #include <rpc/rpc.h>
  900. #include <sys/socket.h>
  901. #include <sys/time.h>
  902. #include <netdb.h>
  903.  
  904. static struct proglst {
  905.     char *(*p_progname)();
  906.     int  p_prognum;
  907.     int  p_procnum;
  908.     xdrproc_t p_inproc, p_outproc;
  909.     struct proglst *p_nxt;
  910. } *proglst;
  911. static void universal();
  912. static SVCXPRT *transp;
  913. struct proglst *pl;
  914.  
  915. registerrpc(prognum, versnum, procnum, progname, inproc, outproc)
  916.     char *(*progname)();
  917.     xdrproc_t inproc, outproc;
  918. {
  919.     
  920.     if (procnum == NULLPROC) {
  921.         (void) fprintf(stderr,
  922.             "can't reassign procedure number %d\n", NULLPROC);
  923.         return (-1);
  924.     }
  925.     if (transp == 0) {
  926.         transp = svcudp_create(RPC_ANYSOCK);
  927.         if (transp == NULL) {
  928.             (void) fprintf(stderr, "couldn't create an rpc server\n");
  929.             return (-1);
  930.         }
  931.     }
  932.     (void) pmap_unset((u_long)prognum, (u_long)versnum);
  933.     if (!svc_register(transp, (u_long)prognum, (u_long)versnum, 
  934.         universal, IPPROTO_UDP)) {
  935.             (void) fprintf(stderr, "couldn't register prog %d vers %d\n",
  936.             prognum, versnum);
  937.         return (-1);
  938.     }
  939.     pl = (struct proglst *)malloc(sizeof(struct proglst));
  940.     if (pl == NULL) {
  941.         (void) fprintf(stderr, "registerrpc: out of memory\n");
  942.         return (-1);
  943.     }
  944.     pl->p_progname = progname;
  945.     pl->p_prognum = prognum;
  946.     pl->p_procnum = procnum;
  947.     pl->p_inproc = inproc;
  948.     pl->p_outproc = outproc;
  949.     pl->p_nxt = proglst;
  950.     proglst = pl;
  951.     return (0);
  952. }
  953.  
  954. static void
  955. universal(rqstp, transp)
  956.     struct svc_req *rqstp;
  957.     SVCXPRT *transp;
  958. {
  959.     int prog, proc;
  960.     char *outdata;
  961.     char xdrbuf[UDPMSGSIZE];
  962.     struct proglst *pl;
  963.  
  964.     /* 
  965.      * enforce "procnum 0 is echo" convention
  966.      */
  967.     if (rqstp->rq_proc == NULLPROC) {
  968.         if (svc_sendreply(transp, xdr_void, (char *)NULL) == FALSE) {
  969.             (void) fprintf(stderr, "xxx\n");
  970.             exit(1);
  971.         }
  972.         return;
  973.     }
  974.     prog = rqstp->rq_prog;
  975.     proc = rqstp->rq_proc;
  976.     for (pl = proglst; pl != NULL; pl = pl->p_nxt)
  977.         if (pl->p_prognum == prog && pl->p_procnum == proc) {
  978.             /* decode arguments into a CLEAN buffer */
  979.             bzero(xdrbuf, sizeof(xdrbuf)); /* required ! */
  980.             if (!svc_getargs(transp, pl->p_inproc, xdrbuf)) {
  981.                 svcerr_decode(transp);
  982.                 return;
  983.             }
  984.             outdata = (*(pl->p_progname))(xdrbuf);
  985.             if (outdata == NULL && pl->p_outproc != xdr_void)
  986.                 /* there was an error */
  987.                 return;
  988.             if (!svc_sendreply(transp, pl->p_outproc, outdata)) {
  989.                 (void) fprintf(stderr,
  990.                     "trouble replying to prog %d\n",
  991.                     pl->p_prognum);
  992.                 exit(1);
  993.             }
  994.             /* free the decoded arguments */
  995.             (void)svc_freeargs(transp, pl->p_inproc, xdrbuf);
  996.             return;
  997.         }
  998.     (void) fprintf(stderr, "never registered prog %d\n", prog);
  999.     exit(1);
  1000. }
  1001.  
  1002. Funky_Stuff
  1003. len=`wc -c < svc_simple.c`
  1004. if [ $len !=     4088 ] ; then
  1005.   echo error: svc_simple.c was $len bytes long, should have been     4088
  1006. fi
  1007. echo x - svc_tcp.c
  1008. cat > svc_tcp.c <<'Funky_Stuff'
  1009. /* @(#)svc_tcp.c    1.2 87/11/09 3.9 RPCSRC */
  1010. /*
  1011.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  1012.  * unrestricted use provided that this legend is included on all tape
  1013.  * media and as a part of the software program in whole or part.  Users
  1014.  * may copy or modify Sun RPC without charge, but are not authorized
  1015.  * to license or distribute it to anyone else except as part of a product or
  1016.  * program developed by the user.
  1017.  * 
  1018.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  1019.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  1020.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  1021.  * 
  1022.  * Sun RPC is provided with no support and without any obligation on the
  1023.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  1024.  * modification or enhancement.
  1025.  * 
  1026.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  1027.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  1028.  * OR ANY PART THEREOF.
  1029.  * 
  1030.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  1031.  * or profits or other special, indirect and consequential damages, even if
  1032.  * Sun has been advised of the possibility of such damages.
  1033.  * 
  1034.  * Sun Microsystems, Inc.
  1035.  * 2550 Garcia Avenue
  1036.  * Mountain View, California  94043
  1037.  */
  1038. #if !defined(lint) && defined(SCCSIDS)
  1039. static char sccsid[] = "@(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro";
  1040. #endif
  1041.  
  1042. /*
  1043.  * svc_tcp.c, Server side for TCP/IP based RPC. 
  1044.  *
  1045.  * Copyright (C) 1984, Sun Microsystems, Inc.
  1046.  *
  1047.  * Actually implements two flavors of transporter -
  1048.  * a tcp rendezvouser (a listner and connection establisher)
  1049.  * and a record/tcp stream.
  1050.  */
  1051.  
  1052. #include <stdio.h>
  1053. #include <rpc/rpc.h>
  1054. #include <sys/socket.h>
  1055. #include <sys/time.h>
  1056. #include <errno.h>
  1057. extern bool_t abort();
  1058. extern errno;
  1059.  
  1060. /*
  1061.  * Ops vector for TCP/IP based rpc service handle
  1062.  */
  1063. static bool_t        svctcp_recv();
  1064. static enum xprt_stat    svctcp_stat();
  1065. static bool_t        svctcp_getargs();
  1066. static bool_t        svctcp_reply();
  1067. static bool_t        svctcp_freeargs();
  1068. static void        svctcp_destroy();
  1069.  
  1070. static struct xp_ops svctcp_op = {
  1071.     svctcp_recv,
  1072.     svctcp_stat,
  1073.     svctcp_getargs,
  1074.     svctcp_reply,
  1075.     svctcp_freeargs,
  1076.     svctcp_destroy
  1077. };
  1078.  
  1079. /*
  1080.  * Ops vector for TCP/IP rendezvous handler
  1081.  */
  1082. static bool_t        rendezvous_request();
  1083. static enum xprt_stat    rendezvous_stat();
  1084.  
  1085. static struct xp_ops svctcp_rendezvous_op = {
  1086.     rendezvous_request,
  1087.     rendezvous_stat,
  1088.     abort,
  1089.     abort,
  1090.     abort,
  1091.     svctcp_destroy
  1092. };
  1093.  
  1094. static int readtcp(), writetcp();
  1095. static SVCXPRT *makefd_xprt();
  1096.  
  1097. struct tcp_rendezvous { /* kept in xprt->xp_p1 */
  1098.     u_int sendsize;
  1099.     u_int recvsize;
  1100. };
  1101.  
  1102. struct tcp_conn {  /* kept in xprt->xp_p1 */
  1103.     enum xprt_stat strm_stat;
  1104.     u_long x_id;
  1105.     XDR xdrs;
  1106.     char verf_body[MAX_AUTH_BYTES];
  1107. };
  1108.  
  1109. /*
  1110.  * Usage:
  1111.  *    xprt = svctcp_create(sock, send_buf_size, recv_buf_size);
  1112.  *
  1113.  * Creates, registers, and returns a (rpc) tcp based transporter.
  1114.  * Once *xprt is initialized, it is registered as a transporter
  1115.  * see (svc.h, xprt_register).  This routine returns
  1116.  * a NULL if a problem occurred.
  1117.  *
  1118.  * If sock<0 then a socket is created, else sock is used.
  1119.  * If the socket, sock is not bound to a port then svctcp_create
  1120.  * binds it to an arbitrary port.  The routine then starts a tcp
  1121.  * listener on the socket's associated port.  In any (successful) case,
  1122.  * xprt->xp_sock is the registered socket number and xprt->xp_port is the
  1123.  * associated port number.
  1124.  *
  1125.  * Since tcp streams do buffered io similar to stdio, the caller can specify
  1126.  * how big the send and receive buffers are via the second and third parms;
  1127.  * 0 => use the system default.
  1128.  */
  1129. SVCXPRT *
  1130. svctcp_create(sock, sendsize, recvsize)
  1131.     register int sock;
  1132.     u_int sendsize;
  1133.     u_int recvsize;
  1134. {
  1135.     bool_t madesock = FALSE;
  1136.     register SVCXPRT *xprt;
  1137.     register struct tcp_rendezvous *r;
  1138.     struct sockaddr_in addr;
  1139.     int len = sizeof(struct sockaddr_in);
  1140.  
  1141.     if (sock == RPC_ANYSOCK) {
  1142.         if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
  1143.             perror("svctcp_.c - udp socket creation problem");
  1144.             return ((SVCXPRT *)NULL);
  1145.         }
  1146.         madesock = TRUE;
  1147.     }
  1148.     bzero((char *)&addr, sizeof (addr));
  1149.     addr.sin_family = AF_INET;
  1150.     if (bindresvport(sock, &addr)) {
  1151.         addr.sin_port = 0;
  1152.         (void)bind(sock, (struct sockaddr *)&addr, len);
  1153.     }
  1154.     if ((getsockname(sock, (struct sockaddr *)&addr, &len) != 0)  ||
  1155.         (listen(sock, 2) != 0)) {
  1156.         perror("svctcp_.c - cannot getsockname or listen");
  1157.         if (madesock)
  1158.                (void)close(sock);
  1159.         return ((SVCXPRT *)NULL);
  1160.     }
  1161.     r = (struct tcp_rendezvous *)mem_alloc(sizeof(*r));
  1162.     if (r == NULL) {
  1163.         (void) fprintf(stderr, "svctcp_create: out of memory\n");
  1164.         return (NULL);
  1165.     }
  1166.     r->sendsize = sendsize;
  1167.     r->recvsize = recvsize;
  1168.     xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
  1169.     if (xprt == NULL) {
  1170.         (void) fprintf(stderr, "svctcp_create: out of memory\n");
  1171.         return (NULL);
  1172.     }
  1173.     xprt->xp_p2 = NULL;
  1174.     xprt->xp_p1 = (caddr_t)r;
  1175.     xprt->xp_verf = _null_auth;
  1176.     xprt->xp_ops = &svctcp_rendezvous_op;
  1177.     xprt->xp_port = ntohs(addr.sin_port);
  1178.     xprt->xp_sock = sock;
  1179.     xprt_register(xprt);
  1180.     return (xprt);
  1181. }
  1182.  
  1183. /*
  1184.  * Like svtcp_create(), except the routine takes any *open* UNIX file
  1185.  * descriptor as its first input.
  1186.  */
  1187. SVCXPRT *
  1188. svcfd_create(fd, sendsize, recvsize)
  1189.     int fd;
  1190.     u_int sendsize;
  1191.     u_int recvsize;
  1192. {
  1193.  
  1194.     return (makefd_xprt(fd, sendsize, recvsize));
  1195. }
  1196.  
  1197. static SVCXPRT *
  1198. makefd_xprt(fd, sendsize, recvsize)
  1199.     int fd;
  1200.     u_int sendsize;
  1201.     u_int recvsize;
  1202. {
  1203.     register SVCXPRT *xprt;
  1204.     register struct tcp_conn *cd;
  1205.  
  1206.     xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
  1207.     if (xprt == (SVCXPRT *)NULL) {
  1208.         (void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n");
  1209.         goto done;
  1210.     }
  1211.     cd = (struct tcp_conn *)mem_alloc(sizeof(struct tcp_conn));
  1212.     if (cd == (struct tcp_conn *)NULL) {
  1213.         (void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n");
  1214.         mem_free((char *) xprt, sizeof(SVCXPRT));
  1215.         xprt = (SVCXPRT *)NULL;
  1216.         goto done;
  1217.     }
  1218.     cd->strm_stat = XPRT_IDLE;
  1219.     xdrrec_create(&(cd->xdrs), sendsize, recvsize,
  1220.         (caddr_t)xprt, readtcp, writetcp);
  1221.     xprt->xp_p2 = NULL;
  1222.     xprt->xp_p1 = (caddr_t)cd;
  1223.     xprt->xp_verf.oa_base = cd->verf_body;
  1224.     xprt->xp_addrlen = 0;
  1225.     xprt->xp_ops = &svctcp_op;  /* truely deals with calls */
  1226.     xprt->xp_port = 0;  /* this is a connection, not a rendezvouser */
  1227.     xprt->xp_sock = fd;
  1228.     xprt_register(xprt);
  1229.     done:
  1230.     return (xprt);
  1231. }
  1232.  
  1233. static bool_t
  1234. rendezvous_request(xprt)
  1235.     register SVCXPRT *xprt;
  1236. {
  1237.     int sock;
  1238.     struct tcp_rendezvous *r;
  1239.     struct sockaddr_in addr;
  1240.     int len;
  1241.  
  1242.     r = (struct tcp_rendezvous *)xprt->xp_p1;
  1243.     again:
  1244.     len = sizeof(struct sockaddr_in);
  1245.     if ((sock = accept(xprt->xp_sock, (struct sockaddr *)&addr,
  1246.         &len)) < 0) {
  1247.         if (errno == EINTR)
  1248.             goto again;
  1249.            return (FALSE);
  1250.     }
  1251.     /*
  1252.      * make a new transporter (re-uses xprt)
  1253.      */
  1254.     xprt = makefd_xprt(sock, r->sendsize, r->recvsize);
  1255.     xprt->xp_raddr = addr;
  1256.     xprt->xp_addrlen = len;
  1257.     return (FALSE); /* there is never an rpc msg to be processed */
  1258. }
  1259.  
  1260. static enum xprt_stat
  1261. rendezvous_stat()
  1262. {
  1263.  
  1264.     return (XPRT_IDLE);
  1265. }
  1266.  
  1267. static void
  1268. svctcp_destroy(xprt)
  1269.     register SVCXPRT *xprt;
  1270. {
  1271.     register struct tcp_conn *cd = (struct tcp_conn *)xprt->xp_p1;
  1272.  
  1273.     xprt_unregister(xprt);
  1274.     (void)close(xprt->xp_sock);
  1275.     if (xprt->xp_port != 0) {
  1276.         /* a rendezvouser socket */
  1277.         xprt->xp_port = 0;
  1278.     } else {
  1279.         /* an actual connection socket */
  1280.         XDR_DESTROY(&(cd->xdrs));
  1281.     }
  1282.     mem_free((caddr_t)cd, sizeof(struct tcp_conn));
  1283.     mem_free((caddr_t)xprt, sizeof(SVCXPRT));
  1284. }
  1285.  
  1286. /*
  1287.  * All read operations timeout after 35 seconds.
  1288.  * A timeout is fatal for the connection.
  1289.  */
  1290. static struct timeval wait_per_try = { 35, 0 };
  1291.  
  1292. /*
  1293.  * reads data from the tcp conection.
  1294.  * any error is fatal and the connection is closed.
  1295.  * (And a read of zero bytes is a half closed stream => error.)
  1296.  */
  1297. static int
  1298. readtcp(xprt, buf, len)
  1299.     register SVCXPRT *xprt;
  1300.     caddr_t buf;
  1301.     register int len;
  1302. {
  1303.     register int sock = xprt->xp_sock;
  1304. #ifdef FD_SETSIZE
  1305.     fd_set mask;
  1306.     fd_set readfds;
  1307.  
  1308.     FD_ZERO(&mask);
  1309.     FD_SET(sock, &mask);
  1310. #else
  1311.     register int mask = 1 << sock;
  1312.     int readfds;
  1313. #endif /* def FD_SETSIZE */
  1314.     do {
  1315.         readfds = mask;
  1316.         if (select(_rpc_dtablesize(), &readfds, (int*)NULL, (int*)NULL, 
  1317.                &wait_per_try) <= 0) {
  1318.             if (errno == EINTR) {
  1319.                 continue;
  1320.             }
  1321.             goto fatal_err;
  1322.         }
  1323. #ifdef FD_SETSIZE
  1324.     } while (!FD_ISSET(sock, &readfds));
  1325. #else
  1326.     } while (readfds != mask);
  1327. #endif /* def FD_SETSIZE */
  1328.     if ((len = read(sock, buf, len)) > 0) {
  1329.         return (len);
  1330.     }
  1331. fatal_err:
  1332.     ((struct tcp_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED;
  1333.     return (-1);
  1334. }
  1335.  
  1336. /*
  1337.  * writes data to the tcp connection.
  1338.  * Any error is fatal and the connection is closed.
  1339.  */
  1340. static int
  1341. writetcp(xprt, buf, len)
  1342.     register SVCXPRT *xprt;
  1343.     caddr_t buf;
  1344.     int len;
  1345. {
  1346.     register int i, cnt;
  1347.  
  1348.     for (cnt = len; cnt > 0; cnt -= i, buf += i) {
  1349.         if ((i = write(xprt->xp_sock, buf, cnt)) < 0) {
  1350.             ((struct tcp_conn *)(xprt->xp_p1))->strm_stat =
  1351.                 XPRT_DIED;
  1352.             return (-1);
  1353.         }
  1354.     }
  1355.     return (len);
  1356. }
  1357.  
  1358. static enum xprt_stat
  1359. svctcp_stat(xprt)
  1360.     SVCXPRT *xprt;
  1361. {
  1362.     register struct tcp_conn *cd =
  1363.         (struct tcp_conn *)(xprt->xp_p1);
  1364.  
  1365.     if (cd->strm_stat == XPRT_DIED)
  1366.         return (XPRT_DIED);
  1367.     if (! xdrrec_eof(&(cd->xdrs)))
  1368.         return (XPRT_MOREREQS);
  1369.     return (XPRT_IDLE);
  1370. }
  1371.  
  1372. static bool_t
  1373. svctcp_recv(xprt, msg)
  1374.     SVCXPRT *xprt;
  1375.     register struct rpc_msg *msg;
  1376. {
  1377.     register struct tcp_conn *cd =
  1378.         (struct tcp_conn *)(xprt->xp_p1);
  1379.     register XDR *xdrs = &(cd->xdrs);
  1380.  
  1381.     xdrs->x_op = XDR_DECODE;
  1382.     (void)xdrrec_skiprecord(xdrs);
  1383.     if (xdr_callmsg(xdrs, msg)) {
  1384.         cd->x_id = msg->rm_xid;
  1385.         return (TRUE);
  1386.     }
  1387.     return (FALSE);
  1388. }
  1389.  
  1390. static bool_t
  1391. svctcp_getargs(xprt, xdr_args, args_ptr)
  1392.     SVCXPRT *xprt;
  1393.     xdrproc_t xdr_args;
  1394.     caddr_t args_ptr;
  1395. {
  1396.  
  1397.     return ((*xdr_args)(&(((struct tcp_conn *)(xprt->xp_p1))->xdrs), args_ptr));
  1398. }
  1399.  
  1400. static bool_t
  1401. svctcp_freeargs(xprt, xdr_args, args_ptr)
  1402.     SVCXPRT *xprt;
  1403.     xdrproc_t xdr_args;
  1404.     caddr_t args_ptr;
  1405. {
  1406.     register XDR *xdrs =
  1407.         &(((struct tcp_conn *)(xprt->xp_p1))->xdrs);
  1408.  
  1409.     xdrs->x_op = XDR_FREE;
  1410.     return ((*xdr_args)(xdrs, args_ptr));
  1411. }
  1412.  
  1413. static bool_t
  1414. svctcp_reply(xprt, msg)
  1415.     SVCXPRT *xprt;
  1416.     register struct rpc_msg *msg;
  1417. {
  1418.     register struct tcp_conn *cd =
  1419.         (struct tcp_conn *)(xprt->xp_p1);
  1420.     register XDR *xdrs = &(cd->xdrs);
  1421.     register bool_t stat;
  1422.  
  1423.     xdrs->x_op = XDR_ENCODE;
  1424.     msg->rm_xid = cd->x_id;
  1425.     stat = xdr_replymsg(xdrs, msg);
  1426.     (void)xdrrec_endofrecord(xdrs, TRUE);
  1427.     return (stat);
  1428. }
  1429. Funky_Stuff
  1430. len=`wc -c < svc_tcp.c`
  1431. if [ $len !=    10278 ] ; then
  1432.   echo error: svc_tcp.c was $len bytes long, should have been    10278
  1433. fi
  1434. echo x - svc_udp.c
  1435. cat > svc_udp.c <<'Funky_Stuff'
  1436. /* @(#)svc_udp.c    1.1 87/11/04 3.9 RPCSRC */
  1437. /*
  1438.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  1439.  * unrestricted use provided that this legend is included on all tape
  1440.  * media and as a part of the software program in whole or part.  Users
  1441.  * may copy or modify Sun RPC without charge, but are not authorized
  1442.  * to license or distribute it to anyone else except as part of a product or
  1443.  * program developed by the user.
  1444.  * 
  1445.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  1446.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  1447.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  1448.  * 
  1449.  * Sun RPC is provided with no support and without any obligation on the
  1450.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  1451.  * modification or enhancement.
  1452.  * 
  1453.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  1454.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  1455.  * OR ANY PART THEREOF.
  1456.  * 
  1457.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  1458.  * or profits or other special, indirect and consequential damages, even if
  1459.  * Sun has been advised of the possibility of such damages.
  1460.  * 
  1461.  * Sun Microsystems, Inc.
  1462.  * 2550 Garcia Avenue
  1463.  * Mountain View, California  94043
  1464.  */
  1465. #if !defined(lint) && defined(SCCSIDS)
  1466. static char sccsid[] = "@(#)svc_udp.c 1.21 87/08/11 Copyr 1984 Sun Micro";
  1467. #endif
  1468.  
  1469. /*
  1470.  * svc_udp.c,
  1471.  * Server side for UDP/IP based RPC.  (Does some caching in the hopes of
  1472.  * achieving execute-at-most-once semantics.)
  1473.  *
  1474.  * Copyright (C) 1984, Sun Microsystems, Inc.
  1475.  */
  1476.  
  1477. #include <stdio.h>
  1478. #include <rpc/rpc.h>
  1479. #include <sys/socket.h>
  1480. #include <errno.h>
  1481.  
  1482.  
  1483. #define rpc_buffer(xprt) ((xprt)->xp_p1)
  1484. #define MAX(a, b)     ((a > b) ? a : b)
  1485.  
  1486. static bool_t        svcudp_recv();
  1487. static bool_t        svcudp_reply();
  1488. static enum xprt_stat    svcudp_stat();
  1489. static bool_t        svcudp_getargs();
  1490. static bool_t        svcudp_freeargs();
  1491. static void        svcudp_destroy();
  1492.  
  1493. static struct xp_ops svcudp_op = {
  1494.     svcudp_recv,
  1495.     svcudp_stat,
  1496.     svcudp_getargs,
  1497.     svcudp_reply,
  1498.     svcudp_freeargs,
  1499.     svcudp_destroy
  1500. };
  1501.  
  1502. extern int errno;
  1503.  
  1504. /*
  1505.  * kept in xprt->xp_p2
  1506.  */
  1507. struct svcudp_data {
  1508.     u_int   su_iosz;    /* byte size of send.recv buffer */
  1509.     u_long    su_xid;        /* transaction id */
  1510.     XDR    su_xdrs;    /* XDR handle */
  1511.     char    su_verfbody[MAX_AUTH_BYTES];    /* verifier body */
  1512.     char *     su_cache;    /* cached data, NULL if no cache */
  1513. };
  1514. #define    su_data(xprt)    ((struct svcudp_data *)(xprt->xp_p2))
  1515.  
  1516. /*
  1517.  * Usage:
  1518.  *    xprt = svcudp_create(sock);
  1519.  *
  1520.  * If sock<0 then a socket is created, else sock is used.
  1521.  * If the socket, sock is not bound to a port then svcudp_create
  1522.  * binds it to an arbitrary port.  In any (successful) case,
  1523.  * xprt->xp_sock is the registered socket number and xprt->xp_port is the
  1524.  * associated port number.
  1525.  * Once *xprt is initialized, it is registered as a transporter;
  1526.  * see (svc.h, xprt_register).
  1527.  * The routines returns NULL if a problem occurred.
  1528.  */
  1529. SVCXPRT *
  1530. svcudp_bufcreate(sock, sendsz, recvsz)
  1531.     register int sock;
  1532.     u_int sendsz, recvsz;
  1533. {
  1534.     bool_t madesock = FALSE;
  1535.     register SVCXPRT *xprt;
  1536.     register struct svcudp_data *su;
  1537.     struct sockaddr_in addr;
  1538.     int len = sizeof(struct sockaddr_in);
  1539.  
  1540.     if (sock == RPC_ANYSOCK) {
  1541.         if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
  1542.             perror("svcudp_create: socket creation problem");
  1543.             return ((SVCXPRT *)NULL);
  1544.         }
  1545.         madesock = TRUE;
  1546.     }
  1547.     bzero((char *)&addr, sizeof (addr));
  1548.     addr.sin_family = AF_INET;
  1549.     if (bindresvport(sock, &addr)) {
  1550.         addr.sin_port = 0;
  1551.         (void)bind(sock, (struct sockaddr *)&addr, len);
  1552.     }
  1553.     if (getsockname(sock, (struct sockaddr *)&addr, &len) != 0) {
  1554.         perror("svcudp_create - cannot getsockname");
  1555.         if (madesock)
  1556.             (void)close(sock);
  1557.         return ((SVCXPRT *)NULL);
  1558.     }
  1559.     xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT));
  1560.     if (xprt == NULL) {
  1561.         (void)fprintf(stderr, "svcudp_create: out of memory\n");
  1562.         return (NULL);
  1563.     }
  1564.     su = (struct svcudp_data *)mem_alloc(sizeof(*su));
  1565.     if (su == NULL) {
  1566.         (void)fprintf(stderr, "svcudp_create: out of memory\n");
  1567.         return (NULL);
  1568.     }
  1569.     su->su_iosz = ((MAX(sendsz, recvsz) + 3) / 4) * 4;
  1570.     if ((rpc_buffer(xprt) = mem_alloc(su->su_iosz)) == NULL) {
  1571.         (void)fprintf(stderr, "svcudp_create: out of memory\n");
  1572.         return (NULL);
  1573.     }
  1574.     xdrmem_create(
  1575.         &(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_DECODE);
  1576.     su->su_cache = NULL;
  1577.     xprt->xp_p2 = (caddr_t)su;
  1578.     xprt->xp_verf.oa_base = su->su_verfbody;
  1579.     xprt->xp_ops = &svcudp_op;
  1580.     xprt->xp_port = ntohs(addr.sin_port);
  1581.     xprt->xp_sock = sock;
  1582.     xprt_register(xprt);
  1583.     return (xprt);
  1584. }
  1585.  
  1586. SVCXPRT *
  1587. svcudp_create(sock)
  1588.     int sock;
  1589. {
  1590.  
  1591.     return(svcudp_bufcreate(sock, UDPMSGSIZE, UDPMSGSIZE));
  1592. }
  1593.  
  1594. static enum xprt_stat
  1595. svcudp_stat(xprt)
  1596.     SVCXPRT *xprt;
  1597. {
  1598.  
  1599.     return (XPRT_IDLE); 
  1600. }
  1601.  
  1602. static bool_t
  1603. svcudp_recv(xprt, msg)
  1604.     register SVCXPRT *xprt;
  1605.     struct rpc_msg *msg;
  1606. {
  1607.     register struct svcudp_data *su = su_data(xprt);
  1608.     register XDR *xdrs = &(su->su_xdrs);
  1609.     register int rlen;
  1610.     char *reply;
  1611.     u_long replylen;
  1612.  
  1613.     again:
  1614.     xprt->xp_addrlen = sizeof(struct sockaddr_in);
  1615.     rlen = recvfrom(xprt->xp_sock, rpc_buffer(xprt), (int) su->su_iosz,
  1616.         0, (struct sockaddr *)&(xprt->xp_raddr), &(xprt->xp_addrlen));
  1617.     if (rlen == -1 && errno == EINTR)
  1618.         goto again;
  1619.     if (rlen < 4*sizeof(u_long))
  1620.         return (FALSE);
  1621.     xdrs->x_op = XDR_DECODE;
  1622.     XDR_SETPOS(xdrs, 0);
  1623.     if (! xdr_callmsg(xdrs, msg))
  1624.         return (FALSE);
  1625.     su->su_xid = msg->rm_xid;
  1626.     if (su->su_cache != NULL) {
  1627.         if (cache_get(xprt, msg, &reply, &replylen)) {
  1628.             (void) sendto(xprt->xp_sock, reply, (int) replylen, 0,
  1629.               (struct sockaddr *) &xprt->xp_raddr, (int) &xprt->xp_addrlen);    
  1630.             return(FALSE);
  1631.         }
  1632.     }
  1633.     return (TRUE);
  1634. }
  1635.  
  1636. static bool_t
  1637. svcudp_reply(xprt, msg)
  1638.     register SVCXPRT *xprt; 
  1639.     struct rpc_msg *msg; 
  1640. {
  1641.     register struct svcudp_data *su = su_data(xprt);
  1642.     register XDR *xdrs = &(su->su_xdrs);
  1643.     register int slen;
  1644.     register bool_t stat = FALSE;
  1645.  
  1646.     xdrs->x_op = XDR_ENCODE;
  1647.     XDR_SETPOS(xdrs, 0);
  1648.     msg->rm_xid = su->su_xid;
  1649.     if (xdr_replymsg(xdrs, msg)) {
  1650.         slen = (int)XDR_GETPOS(xdrs);
  1651.         if (sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0,
  1652.             (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen)
  1653.             == slen) {
  1654.             stat = TRUE;
  1655.             if (su->su_cache && slen >= 0) {
  1656.                 cache_set(xprt, (u_long) slen);
  1657.             }
  1658.         }
  1659.     }
  1660.     return (stat);
  1661. }
  1662.  
  1663. static bool_t
  1664. svcudp_getargs(xprt, xdr_args, args_ptr)
  1665.     SVCXPRT *xprt;
  1666.     xdrproc_t xdr_args;
  1667.     caddr_t args_ptr;
  1668. {
  1669.  
  1670.     return ((*xdr_args)(&(su_data(xprt)->su_xdrs), args_ptr));
  1671. }
  1672.  
  1673. static bool_t
  1674. svcudp_freeargs(xprt, xdr_args, args_ptr)
  1675.     SVCXPRT *xprt;
  1676.     xdrproc_t xdr_args;
  1677.     caddr_t args_ptr;
  1678. {
  1679.     register XDR *xdrs = &(su_data(xprt)->su_xdrs);
  1680.  
  1681.     xdrs->x_op = XDR_FREE;
  1682.     return ((*xdr_args)(xdrs, args_ptr));
  1683. }
  1684.  
  1685. static void
  1686. svcudp_destroy(xprt)
  1687.     register SVCXPRT *xprt;
  1688. {
  1689.     register struct svcudp_data *su = su_data(xprt);
  1690.  
  1691.     xprt_unregister(xprt);
  1692.     (void)close(xprt->xp_sock);
  1693.     XDR_DESTROY(&(su->su_xdrs));
  1694.     mem_free(rpc_buffer(xprt), su->su_iosz);
  1695.     mem_free((caddr_t)su, sizeof(struct svcudp_data));
  1696.     mem_free((caddr_t)xprt, sizeof(SVCXPRT));
  1697. }
  1698.  
  1699.  
  1700. /***********this could be a separate file*********************/
  1701.  
  1702. /*
  1703.  * Fifo cache for udp server
  1704.  * Copies pointers to reply buffers into fifo cache
  1705.  * Buffers are sent again if retransmissions are detected.
  1706.  */
  1707.  
  1708. #define SPARSENESS 4    /* 75% sparse */
  1709.  
  1710. #define CACHE_PERROR(msg)    \
  1711.     (void) fprintf(stderr,"%s\n", msg)
  1712.  
  1713. #define ALLOC(type, size)    \
  1714.     (type *) mem_alloc((unsigned) (sizeof(type) * (size)))
  1715.  
  1716. #define BZERO(addr, type, size)     \
  1717.     bzero((char *) addr, sizeof(type) * (int) (size)) 
  1718.  
  1719. /*
  1720.  * An entry in the cache
  1721.  */
  1722. typedef struct cache_node *cache_ptr;
  1723. struct cache_node {
  1724.     /*
  1725.      * Index into cache is xid, proc, vers, prog and address
  1726.      */
  1727.     u_long cache_xid;
  1728.     u_long cache_proc;
  1729.     u_long cache_vers;
  1730.     u_long cache_prog;
  1731.     struct sockaddr_in cache_addr;
  1732.     /*
  1733.      * The cached reply and length
  1734.      */
  1735.     char * cache_reply;
  1736.     u_long cache_replylen;
  1737.     /*
  1738.       * Next node on the list, if there is a collision
  1739.      */
  1740.     cache_ptr cache_next;    
  1741. };
  1742.  
  1743.  
  1744.  
  1745. /*
  1746.  * The entire cache
  1747.  */
  1748. struct udp_cache {
  1749.     u_long uc_size;        /* size of cache */
  1750.     cache_ptr *uc_entries;    /* hash table of entries in cache */
  1751.     cache_ptr *uc_fifo;    /* fifo list of entries in cache */
  1752.     u_long uc_nextvictim;    /* points to next victim in fifo list */
  1753.     u_long uc_prog;        /* saved program number */
  1754.     u_long uc_vers;        /* saved version number */
  1755.     u_long uc_proc;        /* saved procedure number */
  1756.     struct sockaddr_in uc_addr; /* saved caller's address */
  1757. };
  1758.  
  1759.  
  1760. /*
  1761.  * the hashing function
  1762.  */
  1763. #define CACHE_LOC(transp, xid)    \
  1764.  (xid % (SPARSENESS*((struct udp_cache *) su_data(transp)->su_cache)->uc_size))    
  1765.  
  1766.  
  1767. /*
  1768.  * Enable use of the cache. 
  1769.  * Note: there is no disable.
  1770.  */
  1771. svcudp_enablecache(transp, size)
  1772.     SVCXPRT *transp;
  1773.     u_long size;
  1774. {
  1775.     struct svcudp_data *su = su_data(transp);
  1776.     struct udp_cache *uc;
  1777.  
  1778.     if (su->su_cache != NULL) {
  1779.         CACHE_PERROR("enablecache: cache already enabled");
  1780.         return(0);    
  1781.     }
  1782.     uc = ALLOC(struct udp_cache, 1);
  1783.     if (uc == NULL) {
  1784.         CACHE_PERROR("enablecache: could not allocate cache");
  1785.         return(0);
  1786.     }
  1787.     uc->uc_size = size;
  1788.     uc->uc_nextvictim = 0;
  1789.     uc->uc_entries = ALLOC(cache_ptr, size * SPARSENESS);
  1790.     if (uc->uc_entries == NULL) {
  1791.         CACHE_PERROR("enablecache: could not allocate cache data");
  1792.         return(0);
  1793.     }
  1794.     BZERO(uc->uc_entries, cache_ptr, size * SPARSENESS);
  1795.     uc->uc_fifo = ALLOC(cache_ptr, size);
  1796.     if (uc->uc_fifo == NULL) {
  1797.         CACHE_PERROR("enablecache: could not allocate cache fifo");
  1798.         return(0);
  1799.     }
  1800.     BZERO(uc->uc_fifo, cache_ptr, size);
  1801.     su->su_cache = (char *) uc;
  1802.     return(1);
  1803. }
  1804.  
  1805.  
  1806. /*
  1807.  * Set an entry in the cache
  1808.  */
  1809. static
  1810. cache_set(xprt, replylen)
  1811.     SVCXPRT *xprt;
  1812.     u_long replylen;    
  1813. {
  1814.     register cache_ptr victim;    
  1815.     register cache_ptr *vicp;
  1816.     register struct svcudp_data *su = su_data(xprt);
  1817.     struct udp_cache *uc = (struct udp_cache *) su->su_cache;
  1818.     u_int loc;
  1819.     char *newbuf;
  1820.  
  1821.     /*
  1822.       * Find space for the new entry, either by
  1823.      * reusing an old entry, or by mallocing a new one
  1824.      */
  1825.     victim = uc->uc_fifo[uc->uc_nextvictim];
  1826.     if (victim != NULL) {
  1827.         loc = CACHE_LOC(xprt, victim->cache_xid);
  1828.         for (vicp = &uc->uc_entries[loc]; 
  1829.           *vicp != NULL && *vicp != victim; 
  1830.           vicp = &(*vicp)->cache_next) 
  1831.                 ;
  1832.         if (*vicp == NULL) {
  1833.             CACHE_PERROR("cache_set: victim not found");
  1834.             return;
  1835.         }
  1836.         *vicp = victim->cache_next;    /* remote from cache */
  1837.         newbuf = victim->cache_reply;
  1838.     } else {
  1839.         victim = ALLOC(struct cache_node, 1);
  1840.         if (victim == NULL) {
  1841.             CACHE_PERROR("cache_set: victim alloc failed");
  1842.             return;
  1843.         }
  1844.         newbuf = mem_alloc(su->su_iosz);
  1845.         if (newbuf == NULL) {
  1846.             CACHE_PERROR("cache_set: could not allocate new rpc_buffer");
  1847.             return;
  1848.         }
  1849.     }
  1850.  
  1851.     /*
  1852.      * Store it away
  1853.      */
  1854.     victim->cache_replylen = replylen;
  1855.     victim->cache_reply = rpc_buffer(xprt);
  1856.     rpc_buffer(xprt) = newbuf;
  1857.     xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_ENCODE);
  1858.     victim->cache_xid = su->su_xid;
  1859.     victim->cache_proc = uc->uc_proc;
  1860.     victim->cache_vers = uc->uc_vers;
  1861.     victim->cache_prog = uc->uc_prog;
  1862.     victim->cache_addr = uc->uc_addr;
  1863.     loc = CACHE_LOC(xprt, victim->cache_xid);
  1864.     victim->cache_next = uc->uc_entries[loc];    
  1865.     uc->uc_entries[loc] = victim;
  1866.     uc->uc_fifo[uc->uc_nextvictim++] = victim;
  1867.     uc->uc_nextvictim %= uc->uc_size;
  1868. }
  1869.  
  1870. /*
  1871.  * Try to get an entry from the cache
  1872.  * return 1 if found, 0 if not found
  1873.  */
  1874. static
  1875. cache_get(xprt, msg, replyp, replylenp)
  1876.     SVCXPRT *xprt;
  1877.     struct rpc_msg *msg;
  1878.     char **replyp;
  1879.     u_long *replylenp;
  1880. {
  1881.     u_int loc;
  1882.     register cache_ptr ent;
  1883.     register struct svcudp_data *su = su_data(xprt);
  1884.     register struct udp_cache *uc = (struct udp_cache *) su->su_cache;
  1885.  
  1886. #    define EQADDR(a1, a2)    (bcmp((char*)&a1, (char*)&a2, sizeof(a1)) == 0)
  1887.  
  1888.     loc = CACHE_LOC(xprt, su->su_xid);
  1889.     for (ent = uc->uc_entries[loc]; ent != NULL; ent = ent->cache_next) {
  1890.         if (ent->cache_xid == su->su_xid &&
  1891.           ent->cache_proc == uc->uc_proc &&
  1892.           ent->cache_vers == uc->uc_vers &&
  1893.           ent->cache_prog == uc->uc_prog &&
  1894.           EQADDR(ent->cache_addr, uc->uc_addr)) {
  1895.             *replyp = ent->cache_reply;
  1896.             *replylenp = ent->cache_replylen;
  1897.             return(1);
  1898.         }
  1899.     }
  1900.     /*
  1901.      * Failed to find entry
  1902.      * Remember a few things so we can do a set later
  1903.      */
  1904.     uc->uc_proc = msg->rm_call.cb_proc;
  1905.     uc->uc_vers = msg->rm_call.cb_vers;
  1906.     uc->uc_prog = msg->rm_call.cb_prog;
  1907.     uc->uc_addr = xprt->xp_raddr;
  1908.     return(0);
  1909. }
  1910.  
  1911. Funky_Stuff
  1912. len=`wc -c < svc_udp.c`
  1913. if [ $len !=    12207 ] ; then
  1914.   echo error: svc_udp.c was $len bytes long, should have been    12207
  1915. fi
  1916. echo x - types.h
  1917. cat > types.h <<'Funky_Stuff'
  1918. /* @(#)types.h    1.2 87/11/07 3.9 RPCSRC */
  1919. /*
  1920.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  1921.  * unrestricted use provided that this legend is included on all tape
  1922.  * media and as a part of the software program in whole or part.  Users
  1923.  * may copy or modify Sun RPC without charge, but are not authorized
  1924.  * to license or distribute it to anyone else except as part of a product or
  1925.  * program developed by the user.
  1926.  * 
  1927.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  1928.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  1929.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  1930.  * 
  1931.  * Sun RPC is provided with no support and without any obligation on the
  1932.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  1933.  * modification or enhancement.
  1934.  * 
  1935.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  1936.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  1937.  * OR ANY PART THEREOF.
  1938.  * 
  1939.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  1940.  * or profits or other special, indirect and consequential damages, even if
  1941.  * Sun has been advised of the possibility of such damages.
  1942.  * 
  1943.  * Sun Microsystems, Inc.
  1944.  * 2550 Garcia Avenue
  1945.  * Mountain View, California  94043
  1946.  */
  1947. /*      @(#)types.h 1.18 87/07/24 SMI      */
  1948.  
  1949. /*
  1950.  * Rpc additions to <sys/types.h>
  1951.  */
  1952. #ifndef __TYPES_RPC_HEADER__
  1953. #define __TYPES_RPC_HEADER__
  1954.  
  1955. #define    bool_t    int
  1956. #define    enum_t    int
  1957. #define    FALSE    (0)
  1958. #define    TRUE    (1)
  1959. #define __dontcare__    -1
  1960. #ifndef NULL
  1961. #    define NULL 0
  1962. #endif
  1963.  
  1964. extern char *malloc();
  1965. #define mem_alloc(bsize)    malloc(bsize)
  1966. #define mem_free(ptr, bsize)    free(ptr)
  1967.  
  1968. #ifndef makedev /* ie, we haven't already included it */
  1969. #include <sys/types.h>
  1970. #endif
  1971. /*#include <sys/time.h>*/
  1972.  
  1973. #endif /* ndef __TYPES_RPC_HEADER__ */
  1974. Funky_Stuff
  1975. len=`wc -c < types.h`
  1976. if [ $len !=     1847 ] ; then
  1977.   echo error: types.h was $len bytes long, should have been     1847
  1978. fi
  1979. cd ..
  1980. echo more files to follow
  1981. exit
  1982.